package com.easydisk.user.config;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;


@Component
public class RedisServer {

    /** 操作字符串 */
    private ValueOperations<String, String> valueOperations;
    /** 操作hash */
    private HashOperations hashOperations;
    /** 操作list */
    private ListOperations listOperations;
    /** 操作set */
    private SetOperations setOperations;
    /** 操作有序set */
    private ZSetOperations zSetOperations;
    /** Redis模板 */
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 构造方法初始化操作类
     */
    @PostConstruct
    private void inInit() {
        valueOperations = stringRedisTemplate.opsForValue();
        hashOperations = redisTemplate.opsForHash();
        listOperations = stringRedisTemplate.opsForList();
        setOperations = stringRedisTemplate.opsForSet();
        zSetOperations = stringRedisTemplate.opsForZSet();
    }

    /**
     * 从缓存获取值
     *
     * @param key 缓存key
     * @param c   参数类型
     * @param <T> 参数对象
     * @return T 返回对象
     */
    public <T> T getCache(String key, Class<T> c) {
        String cache = getCache(key);
        return JSONObject.parseObject(cache, c);//将json字符串转换为传入的实体类
    }

    public <T> List getCacheForList(String key, Class<T> c) {
        String cache = getCache(key);
        return JSONObject.parseArray(cache, c);
    }
    /**
     * 获取缓存信息
     *
     * @param key 缓存key
     * @return String
     */
    public String getCache(String key) {
        return valueOperations.get(key);
    }

    /**
     * 添加缓存
     *
     * @param key 缓存KEY
     * @param obj 缓存对象
     */
    public void setCache(String key, Object obj) {
        this.setCache(key, JSONObject.toJSONString(obj));
    }

    /**
     * 设置缓存值没有设置过期时间
     *
     * @param key   缓存key
     * @param value 缓存值
     */
    public void setCache(String key, String value) {
        if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
            return;
        }
        valueOperations.set(key, value);
    }


    /**
     * List处理
     * @param key
     * @param list
     */
    public void rightPushAll(String key, List list) {
        if (StringUtils.isEmpty(key) || StringUtils.isEmpty(list)) {
            return;
        }
        List<String> redisList = new ArrayList<>();
        if (list != null && !list.isEmpty() && list.size() > 0) {
            for (Object obj : list) {
                if (obj != null) {
                    redisList.add(JSONObject.toJSONString(obj));
                }
            }
        }
        listOperations.rightPushAll(key, redisList);
    }

    /**
     * 从缓存获取数据
     *
     * @param key 缓存KEY
     * @param c   值类型
     * @param <T> 值对象
     * @return List<T> 返回对象列表
     */
    public <T> List<T> getRedisList(String key, Class<T> c) {
        List<String> listStr = listOperations.range(key, 0, -1);
        if (listStr.isEmpty()) {
            return null;
        }
        List<T> backList = new ArrayList<>();
        for (String str : listStr) {
            if (!StringUtils.isEmpty(str)) {
                backList.add(JSONObject.parseObject(str, c));
            }
        }
        return backList;
    }

    /**
     * 保存到zSet中
     * @param key
     * @param value
     * @param score
     */
    public Boolean setzSetAdd(String key,String value,double score){
        if(StringUtils.isEmpty(key)||StringUtils.isEmpty(value))
            return false;
        zSetOperations.add(key,value,score);
        return true;
    }



    /**
     * 统计范围内zSet的有效数量
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Long zSetGetCount(String key,long start,long end){
        return zSetOperations.count(key,start,end);
    }

    /**
     * 获取 zSet 长度
     * @param key
     * @return
     */
    public Long zSetGetSize(String key){
        return zSetOperations.zCard(key);
    }

    /**
     * 清除窗口过期成员
     * @param key
     * @param start
     * @param end
     */
    public void zSetRemoveRangeByScore(String key,long start,long end){
        zSetOperations.removeRangeByScore(key,start,end);
    }
}
